#ifndef __GLIB_H__
#define __GLIB_H__

#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#ifdef __cplusplus
#define G_BEGIN_DECLS extern "C" {
#define G_END_DECLS }
#else
#define G_BEGIN_DECLS
#define G_END_DECLS
#endif

#define G_GNUC_INTERNAL

typedef char gchar;
typedef unsigned int guint;
typedef bool gboolean;
typedef ssize_t gssize;
typedef size_t gsize;
typedef uint32_t guint32;
typedef int gint;

#define TRUE true
#define FALSE false

typedef struct _GError GError;

#define G_IO_ERROR 1

#define g_strdup(x) strdup(x)
#define g_free(x) free(x)

#define G_FILE_TEST_EXISTS R_OK
int g_file_test(const char* path, int t);

#define g_clear_error(x)
#define g_error_free(x) free(x)
#define g_assert(x) assert(x)

#define G_LIKELY(x) (__builtin_expect(!!(x), 1))
#define G_UNLIKELY(x) (__builtin_expect(!!(x), 0))

#define g_printerr(...) printf(__VA_ARGS__)

#define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))

/////quick.h begin

G_BEGIN_DECLS

typedef guint32 GQuark;

/* Quarks (string<->id association)
 */

GQuark g_quark_try_string(const gchar* string);

GQuark g_quark_from_static_string(const gchar* string);

GQuark g_quark_from_string(const gchar* string);

const gchar* g_quark_to_string(GQuark quark);

#define G_DEFINE_QUARK(QN, q_n)                  \
    GQuark                                       \
        q_n##_quark(void)                        \
    {                                            \
        static GQuark q;                         \
                                                 \
        if G_UNLIKELY (q == 0)                   \
            q = g_quark_from_static_string(#QN); \
                                                 \
        return q;                                \
    }

const gchar* g_intern_string(const gchar* string);

const gchar* g_intern_static_string(const gchar* string);

void g_set_error(GError** err, GQuark domain, gint code, const gchar* format, ...);
gboolean g_error_matches(const GError* error, GQuark domain, gint code);
void g_propagate_error(GError** dest, GError* src);

int g_io_error_from_errno(gint err_no);

struct _GError {
    const char* message;
    GQuark domain;
    gint code;
};

gchar** g_strsplit(const gchar* string, const gchar* delimiter, gint max_tokens);
void g_strfreev(gchar** str_array);

gboolean g_file_get_contents(const gchar* filename, gchar** contents, gsize* length, GError** error);

///////////////////////////////////////////////////////

#if !(defined (G_STMT_START) && defined (G_STMT_END))
#define G_STMT_START  do
#if defined (_MSC_VER) && (_MSC_VER >= 1500)
#define G_STMT_END \
    __pragma(warning(push)) \
    __pragma(warning(disable:4127)) \
    while(0) \
    __pragma(warning(pop))
#else
#define G_STMT_END    while (0)
#endif
#endif


#define g_return_if_fail(expr) \
  G_STMT_START { \
    if (G_LIKELY (expr)) \
      { } \
    else \
      { \
        printf ("%s:%s  %s\n", __FILE__, \
                                  __func__, \
                                  #expr); \
        return; \
      } \
  } G_STMT_END

#define g_return_val_if_fail(expr, val) \
  G_STMT_START { \
    if (G_LIKELY (expr)) \
      { } \
    else \
      { \
        printf ("%s :%s", \
                                  __func__, \
                                  #expr); \
        return (val); \
      } \
  } G_STMT_END

/**
 * g_warn_if_fail:
 * @expr: the expression to check
 *
 * Logs a warning if the expression is not true.
 *
 * Since: 2.16
 */
#define g_warn_if_fail(expr)                                                    \
    do {                                                                        \
        if G_LIKELY (expr)                                                      \
            ;                                                                   \
        else                                                                    \
            printf("warning:%s:%d:%s:%s", __FILE__, __LINE__, __func__, #expr); \
    } while (0)

////////////////////////////
#define g_slice_new(type) ((type*)malloc(sizeof(type)))

G_END_DECLS

/// quick.h end
#endif